package com.rollCall.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.rollCall.common.util.UserHolder;
import com.rollCall.entity.CheckIn;
import com.rollCall.entity.CheckInRecord;
import com.rollCall.entity.Student;
import com.rollCall.entity.result.PageResult;
import com.rollCall.entity.vo.CheckInPageResVo;
import com.rollCall.entity.vo.CheckInRecordVo;
import com.rollCall.entity.vo.CheckInVo;
import com.rollCall.entity.vo.CheckInfoVo;
import com.rollCall.mapper.CheckInMapper;
import com.rollCall.mapper.CheckInRecordMapper;
import com.rollCall.mapper.ClassMapper;
import com.rollCall.service.CheckInService;
import com.rollCall.service.StudentService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.time.temporal.TemporalUnit;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author LiZhiHan
 * @date 2025/2/28
 */
@Service
@Slf4j
@RequiredArgsConstructor
public class CheckInServiceImpl implements CheckInService {

	private final CheckInMapper checkInMapper;

	private final StudentService studentService;

	private final CheckInRecordMapper checkInRecordMapper;

	private final ClassMapper classMapper;

	@Override
	public void addCheckIn(CheckInVo checkInVo) {
		if (checkInVo.getExpireTime() > 5) {
			throw new RuntimeException("签到时间不能超过5分钟!");
		}
		CheckIn checkIn = new CheckIn();
		Long expireTime = checkInVo.getExpireTime();
		LocalDateTime now = LocalDateTime.now();
		checkIn.setCreateTime(now);
		TemporalUnit temporalUnit = ChronoUnit.MINUTES;
		LocalDateTime plus = now.plus(expireTime, temporalUnit);
		checkIn.setAdminId(UserHolder.get());
		checkIn.setClassId(checkInVo.getClassId());
		checkIn.setExpireTime(plus);
		checkIn.setDescription(checkInVo.getDescription());
		checkInMapper.insert(checkIn);
		log.info("创建签到成功");
		// 初始化签到记录
		List<Student> allStudents = studentService.getAllStudents(checkInVo.getClassId());
		for (Student student : allStudents) {
			CheckInRecord checkInRecord = new CheckInRecord();
			checkInRecord.setStudentId(student.getId());
			checkInRecord.setStatus(0);
			checkInRecord.setCheckInId(checkIn.getCheckInId());
			checkInRecordMapper.insert(checkInRecord);
		}
	}

	/**
	 * 分页获取签到列表
	 */
	@Override
	public List<CheckInPageResVo> list() {
		List<CheckIn> checkInList = checkInMapper.selectList(new QueryWrapper<CheckIn>().eq("admin_id", UserHolder.get()));
		return checkInList.stream().map(checkIn -> {
			CheckInPageResVo checkInPageResVo = new CheckInPageResVo();
			checkInPageResVo.setId(checkIn.getCheckInId());
			checkInPageResVo.setClassName(classMapper.selectById(checkIn.getClassId()).getName());
			checkInPageResVo.setExpireTime(checkIn.getExpireTime());
			List<CheckInRecord> checkInRecordList = checkInRecordMapper.selectList(new QueryWrapper<CheckInRecord>().eq("check_in_id", checkIn.getCheckInId()));
			int checkInNum = (int) checkInRecordList.stream().filter(f -> Objects.equals(f.getStatus(), 1)).count();
			checkInPageResVo.setCheckInNum(checkInNum);
			checkInPageResVo.setTotalNum(checkInRecordList.size());
			int unCheckInNum = (int) checkInRecordList.stream().filter(f -> !Objects.equals(f.getStatus(), 1)).count();
			checkInPageResVo.setUnCheckInNum(unCheckInNum);
			checkInPageResVo.setCreateTime(checkIn.getCreateTime());
			return checkInPageResVo;
		}).collect(Collectors.toList());
	}

	@Override
	public CheckInfoVo getCheckInById(Long id) {
		List<CheckInRecord> checkInRecordList = checkInRecordMapper.selectList(new QueryWrapper<CheckInRecord>().eq("check_in_id", id));
		CheckIn checkIn = checkInMapper.selectById(id);
		CheckInfoVo checkInfoVo = new CheckInfoVo();
		checkInfoVo.setId(id);
		checkInfoVo.setClassName(classMapper.selectById(checkIn.getClassId()).getName());
		checkInfoVo.setDescription(checkIn.getDescription());
		checkInfoVo.setExpireTime(checkIn.getExpireTime());

		List<CheckInRecordVo> checkInRecordVos = new ArrayList<>();
		if (CollectionUtil.isNotEmpty(checkInRecordList)) {
			checkInRecordList.forEach(checkInRecord -> {
				CheckInRecordVo checkInRecordVo = new CheckInRecordVo();
				checkInRecordVo.setId(checkInRecord.getRecordId());
				checkInRecordVo.setStudentName(studentService.getStudentById(checkInRecord.getStudentId()).getName());
				checkInRecordVo.setCheckInTime(checkInRecord.getCheckInTime());
				checkInRecordVo.setStatus(checkInRecord.getStatus());
				checkInRecordVos.add(checkInRecordVo);
			});

		}
		int count = (int)checkInRecordVos.stream().filter(f -> f.getStatus() == 1).count();
		checkInfoVo.setCheckInNum( count);
		checkInfoVo.setUnCheckInNum(checkInRecordVos.size() - count);
		checkInfoVo.setTotalNum(checkInRecordVos.size());
		checkInfoVo.setCheckInRecordList(checkInRecordVos);
		return checkInfoVo;
	}
}
